package ext.sim.forces;

import ext.sim.Body;
import java.util.ArrayList;
import math.math;
import static math.vec3.*;
import math.vec3;

/** Physically-correct O(N^2) gravity force. */
public class ForceGrav implements Force
{
    
    private ArrayList<Body> rBodies;
    
    private double mGravConstant;
    
    
    public ForceGrav(
            ArrayList<Body> aBodies, 
            double aFieldAccel)
    {
        this.rBodies = aBodies;
        this.mGravConstant = aFieldAccel;
    }
    
    
    public void apply()
    {
        for (int i = 0;     i < this.rBodies.size() - 1; i++)
        for (int j = i + 1; j < this.rBodies.size();     j++)
        {
            Body A = this.rBodies.get(i);
            Body B = this.rBodies.get(j);
            
            vec3 R = sub(B.mX, A.mX);
            double sqR = lengthSq(R);
            R.mul(math.rsqrt(sqR)); // Normalize R.
            
            double fStrength = this.mGravConstant * A.mMass * B.mMass / sqR;
            
            A.mF.addmul(fStrength, R);
            B.mF.addmul(-fStrength, R);
        }
    }
    
}
